package com.yimils.core.goods.serivce.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yimils.core.goods.config.GoodsConstant;
import com.yimils.core.goods.dto.GoodsAddReq;
import com.yimils.core.goods.dto.GoodsQueryReq;
import com.yimils.core.goods.dto.GoodsUpdateReq;
import com.yimils.core.goods.entity.GoodsEntity;
import com.yimils.core.goods.mapper.GoodsMapper;
import com.yimils.core.goods.serivce.*;
import com.yimils.core.goods.vo.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

@Service("goodsService")
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, GoodsEntity> implements GoodsService {
    @Resource(name = "goodsPictureService")
    GoodsPictureService goodsPictureService;
    @Resource(name = "goodsVideoService")
    GoodsVideoService goodsVideoService;
    @Resource(name = "goodsDescribeService")
    GoodsDescribeService goodsDescribeService;
    @Resource(name = "goodsPersonService")
    GoodsPersonService goodsPersonService;
    @Resource(name = "goodsHotelTypeService")
    GoodsHotelTypeService goodsHotelTypeService;
    @Resource(name = "goodsEnvironmentService")
    GoodsEnvironmentService goodsEnvironmentService;
    @Resource(name = "goodsChestService")
    GoodsChestService goodsChestService;

    String getGoodsCode(Long categoryId) {
        StringBuilder result = null;
        result.append("W");
        result.append(String.format("%04d", categoryId));
        String yearLast = new SimpleDateFormat("yy", Locale.CHINESE).format(Calendar.getInstance().getTime());
        result.append(yearLast);
        for (int i = 0; i < 6; i++) {
            int intVal = (int) (Math.random() * 26 + 97);
            result.append((char) intVal);
        }
        return result.toString();
    }

    @Override
    public Boolean saveGoods(GoodsAddReq goodsAddReq) {

        GoodsEntity goodsEntity = new GoodsEntity();
        goodsEntity.setAudit(GoodsConstant.GoodsAuditState.NOTPASS.getCode());
        goodsEntity.setPutawayState(GoodsConstant.GoodsPutawayState.SOLDOUT.getCode());
        goodsEntity.setPutaway(goodsAddReq.getPutaway());
        goodsEntity.setRank(goodsAddReq.getRank());
        goodsEntity.setCategoryId(goodsAddReq.getCategoryId());
        goodsEntity.setGoodsCode(getGoodsCode(goodsAddReq.getCategoryId()));
        goodsEntity.setGoodsName(goodsAddReq.getGoodsName());
        goodsEntity.setCostPrice(goodsAddReq.getCostPrice());
        goodsEntity.setRetailPrice(goodsAddReq.getRetailPrice());
        goodsEntity.setWholesalePrice(goodsAddReq.getWholesalePrice());
        goodsEntity.setWholesaleSpec(goodsAddReq.getWholesaleSpec());
        goodsEntity.setRetailSalesUnit(goodsAddReq.getRetailSalesUnit());
        goodsEntity.setUpWarning(goodsAddReq.getUpWarning());
        goodsEntity.setDownWarning(goodsAddReq.getDownWarning());
        goodsEntity.setBrandId(goodsAddReq.getBrandId());
        goodsEntity.setOrigin(goodsAddReq.getOrigin());
        goodsEntity.setExpirationDate(goodsAddReq.getExpirationDate());
        goodsEntity.setRetailWeight(goodsAddReq.getRetailWeight());
        goodsEntity.setWholesaleWeight(goodsAddReq.getWholesaleWeight());
        goodsEntity.setLength(goodsAddReq.getLength());
        goodsEntity.setWide(goodsAddReq.getWide());
        goodsEntity.setHigh(goodsAddReq.getHigh());
        goodsEntity.setWholesaleLength(goodsAddReq.getWholesaleLength());
        goodsEntity.setWholesaleWide(goodsAddReq.getWholesaleWide());
        goodsEntity.setWholesaleHigh(goodsAddReq.getWholesaleHigh());
        goodsEntity.setRemarks(goodsAddReq.getRemarks());
        goodsEntity.setCreateUserId(goodsAddReq.getCreateUserId());
        goodsEntity.setState(Boolean.FALSE);
        goodsEntity.setCreateTime(LocalDateTime.now());
        goodsEntity.setUpdateTime(LocalDateTime.now());
        save(goodsEntity);

        List<String> videoUrls = goodsAddReq.getVideoUrls();
        goodsVideoService.saveGoodsVideo(videoUrls, goodsEntity.getId());
        List<String> pictureUrls = goodsAddReq.getPictureUrls();
        goodsPictureService.saveGoodsPicture(pictureUrls, goodsEntity.getId());
        List<String> describeUrls = goodsAddReq.getDescribeUrls();
        goodsDescribeService.saveGoodsPicture(describeUrls, goodsEntity.getId());
        List<Long> personIds = goodsAddReq.getPersonIds();
        goodsPersonService.saveGoodsPerson(personIds, goodsEntity.getId());
        List<Long> hotelTypeIds = goodsAddReq.getHotelTypeIds();
        goodsHotelTypeService.saveGoodsHotelType(hotelTypeIds, goodsEntity.getId());
        List<Long> environmentIds = goodsAddReq.getEnvironmentIds();
        goodsEnvironmentService.saveGoodsEnvironment(environmentIds, goodsEntity.getId());
        List<Long> chestIds = goodsAddReq.getChestIds();
        goodsChestService.saveGoodsChest(chestIds, goodsEntity.getId());

        return Boolean.TRUE;
    }

    @Override
    public Boolean updateGoods(GoodsUpdateReq goodsUpdateReq) {
        QueryWrapper<GoodsEntity> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(GoodsEntity::getId, goodsUpdateReq.getGoodsId())
                .eq(GoodsEntity::getState, Boolean.FALSE)
                .eq(GoodsEntity::getAudit, GoodsConstant.GoodsAuditState.PASS.getCode())
//                .eq(GoodsEntity::getPutawayState, GoodsConstant.GoodsPutawayState.PUTAWAY.getCode())
        ;
        GoodsEntity goodsEntity = getOne(qw);
        goodsEntity.setAudit(GoodsConstant.GoodsAuditState.NOTPASS.getCode());
        goodsEntity.setPutawayState(GoodsConstant.GoodsPutawayState.SOLDOUT.getCode());
        goodsEntity.setPutaway(goodsUpdateReq.getPutaway());
        goodsEntity.setRank(goodsUpdateReq.getRank());
        goodsEntity.setCategoryId(goodsUpdateReq.getCategoryId());
        goodsEntity.setGoodsCode(getGoodsCode(goodsUpdateReq.getCategoryId()));
        goodsEntity.setGoodsName(goodsUpdateReq.getGoodsName());
        goodsEntity.setCostPrice(goodsUpdateReq.getCostPrice());
        goodsEntity.setRetailPrice(goodsUpdateReq.getRetailPrice());
        goodsEntity.setWholesalePrice(goodsUpdateReq.getWholesalePrice());
        goodsEntity.setWholesaleSpec(goodsUpdateReq.getWholesaleSpec());
        goodsEntity.setRetailSalesUnit(goodsUpdateReq.getRetailSalesUnit());
        goodsEntity.setUpWarning(goodsUpdateReq.getUpWarning());
        goodsEntity.setDownWarning(goodsUpdateReq.getDownWarning());
        goodsEntity.setBrandId(goodsUpdateReq.getBrandId());
        goodsEntity.setOrigin(goodsUpdateReq.getOrigin());
        goodsEntity.setExpirationDate(goodsUpdateReq.getExpirationDate());
        goodsEntity.setRetailWeight(goodsUpdateReq.getRetailWeight());
        goodsEntity.setWholesaleWeight(goodsUpdateReq.getWholesaleWeight());
        goodsEntity.setLength(goodsUpdateReq.getLength());
        goodsEntity.setWide(goodsUpdateReq.getWide());
        goodsEntity.setHigh(goodsUpdateReq.getHigh());
        goodsEntity.setWholesaleLength(goodsUpdateReq.getWholesaleLength());
        goodsEntity.setWholesaleWide(goodsUpdateReq.getWholesaleWide());
        goodsEntity.setWholesaleHigh(goodsUpdateReq.getWholesaleHigh());
        goodsEntity.setRemarks(goodsUpdateReq.getRemarks());
        goodsEntity.setCreateUserId(goodsUpdateReq.getCreateUserId());
        goodsEntity.setCreateTime(LocalDateTime.now());
        goodsEntity.setUpdateTime(LocalDateTime.now());
        saveOrUpdate(goodsEntity);
        Long goodsId = goodsEntity.getId();
        List<PictureRes> picture = goodsUpdateReq.getPicture();
        List<Long> pictureIds = picture.stream().map(PictureRes::getPictureId).collect(Collectors.toList());
        goodsPictureService.deleteGoodsPicture(pictureIds, goodsId);
        List<VideoRes> video = goodsUpdateReq.getVideo();
        List<Long> videoIds = video.stream().map(VideoRes::getVideoId).collect(Collectors.toList());
        goodsVideoService.deleteGoodsVideo(videoIds, goodsId);
        List<PictureRes> describe = goodsUpdateReq.getDescribe();
        List<Long> describeIds = describe.stream().map(PictureRes::getPictureId).collect(Collectors.toList());
        goodsDescribeService.deleteGoodsPicture(describeIds, goodsId);
        List<PersonRes> person = goodsUpdateReq.getPerson();
        List<Long> personIds = person.stream().map(PersonRes::getPersonId).collect(Collectors.toList());
        goodsPersonService.deleteGoodsPerson(personIds, goodsId);
        List<EnvironmentRes> environment = goodsUpdateReq.getEnvironment();
        List<Long> environmentIds = environment.stream().map(EnvironmentRes::getEnvironmentId).collect(Collectors.toList());
        goodsEnvironmentService.deleteGoodsEnvironment(environmentIds, goodsId);
        List<HotelTypeRes> hotelType = goodsUpdateReq.getHotelType();
        List<Long> hotelTypeIds = hotelType.stream().map(HotelTypeRes::getHotelTypeId).collect(Collectors.toList());
        goodsHotelTypeService.deleteGoodsHotelType(hotelTypeIds, goodsId);
        List<ChestRes> chest = goodsUpdateReq.getChest();
        List<Long> chestIds = chest.stream().map(ChestRes::getChestId).collect(Collectors.toList());
        goodsChestService.deleteGoodsChest(chestIds, goodsId);

        return null;
    }

    @Override
    public Boolean deleteGoods(List<Long> goodsIds) {
        QueryWrapper<GoodsEntity> qw = new QueryWrapper<>();
        qw.lambda()
                .in(GoodsEntity::getId, goodsIds)
                .eq(GoodsEntity::getState, Boolean.FALSE);
        List<GoodsEntity> entities = list(qw);
        entities.forEach(o -> {
            o.setState(Boolean.TRUE);
            o.setUpdateTime(LocalDateTime.now());
        });
        return saveOrUpdateBatch(entities);
    }

    @Override
    public List<GoodsRes> listGoods(GoodsQueryReq goodsQueryReq) {
        QueryWrapper<GoodsEntity> qw = new QueryWrapper<>();
        if (goodsQueryReq.getCategoryId() != null) {
            qw.lambda().eq(GoodsEntity::getCategoryId, goodsQueryReq.getCategoryId());
        }
        qw.lambda()
                .like(GoodsEntity::getCategoryId, goodsQueryReq.getGoodsCode())
                .like(GoodsEntity::getCategoryId, goodsQueryReq.getGoodsName())
                .eq(GoodsEntity::getCreateUserId, goodsQueryReq.getSupplierId())
                .eq(GoodsEntity::getState, Boolean.FALSE);
        List<GoodsEntity> entities = list(qw);
        List<Long> goodsIds = entities.stream().map(GoodsEntity::getId).collect(Collectors.toList());
        Map<Long, List<GoodsVideoRes>> mapListGoodsVideo = goodsVideoService.mapListGoodsVideo(goodsIds);
        Map<Long, List<GoodsPictureRes>> mapListGoodsPicture = goodsPictureService.mapListGoodsPicture(goodsIds);
        Map<Long, List<GoodsPictureRes>> mapListGoodsDescribe = goodsDescribeService.mapListGoodsPicture(goodsIds);

        Map<Long, List<GoodsPersonRes>> mapListGoodsPerson = goodsPersonService.mapListGoodsPerson(goodsIds);
        Map<Long, List<GoodsEnvironmentRes>> mapListGoodsEnvironment = goodsEnvironmentService.mapListGoodsEnvironment(goodsIds);
        Map<Long, List<GoodsHotelTypeRes>> mapListGoodsHotelType = goodsHotelTypeService.mapListGoodsHotelType(goodsIds);
        Map<Long, List<GoodsChestRes>> mapListGoodsChest = goodsChestService.mapListGoodsChest(goodsIds);

        return entities.stream().map(o -> {
            GoodsRes goodsRes = new GoodsRes();
            goodsRes.setGoodsId(o.getId());
            goodsRes.setAudit(GoodsConstant.GoodsAuditState.getTypeName(o.getAudit()));
            goodsRes.setPutawayState(GoodsConstant.GoodsPutawayState.getTypeName(o.getPutawayState()));
            goodsRes.setPutaway(o.getPutaway());
            goodsRes.setRank(o.getRank());
            goodsRes.setCategoryId(o.getCategoryId());
            goodsRes.setGoodsCode(o.getGoodsCode());
            goodsRes.setGoodsName(o.getGoodsName());
            goodsRes.setCostPrice(o.getCostPrice());
            goodsRes.setRetailPrice(o.getRetailPrice());
            goodsRes.setWholesalePrice(o.getWholesalePrice());
            goodsRes.setWholesaleSpec(o.getWholesaleSpec());
            goodsRes.setRetailSalesUnit(o.getRetailSalesUnit());
            goodsRes.setUpWarning(o.getUpWarning());
            goodsRes.setDownWarning(o.getDownWarning());
            goodsRes.setBrandId(o.getBrandId());
            goodsRes.setOrigin(o.getOrigin());
            goodsRes.setExpirationDate(o.getExpirationDate());
            goodsRes.setRetailWeight(o.getRetailWeight());
            goodsRes.setWholesaleWeight(o.getWholesaleWeight());
            goodsRes.setLength(o.getLength());
            goodsRes.setWide(o.getWide());
            goodsRes.setHigh(o.getHigh());
            goodsRes.setWholesaleLength(o.getWholesaleLength());
            goodsRes.setWholesaleWide(o.getWholesaleWide());
            goodsRes.setWholesaleHigh(o.getWholesaleHigh());
            goodsRes.setRemarks(o.getRemarks());
            goodsRes.setCreateUserId(o.getCreateUserId());

            goodsRes.setPicture(mapListGoodsPicture.get(o.getId()));
            goodsRes.setVideo(mapListGoodsVideo.get(o.getId()));
            goodsRes.setDescribe(mapListGoodsDescribe.get(o.getId()));
            goodsRes.setPerson(mapListGoodsPerson.get(o.getId()));
            goodsRes.setHotelType(mapListGoodsHotelType.get(o.getId()));
            goodsRes.setEnvironment(mapListGoodsEnvironment.get(o.getId()));
            goodsRes.setChest(mapListGoodsChest.get(o.getId()));
            return goodsRes;

        }).collect(Collectors.toList());
    }

    @Override
    public Boolean audit(Long goodsId, String auditState) {

        QueryWrapper<GoodsEntity> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(GoodsEntity::getCategoryId, goodsId)
                .eq(GoodsEntity::getPutawayState, GoodsConstant.GoodsPutawayState.PUTAWAY.getCode())
                .eq(GoodsEntity::getState, Boolean.FALSE);
        GoodsEntity goodsEntity = getOne(qw);
        String typeCode = GoodsConstant.GoodsAuditState.getTypeCode(auditState);
        if (typeCode != null) {
            goodsEntity.setAudit(typeCode);
            goodsEntity.setPutawayState(GoodsConstant.GoodsPutawayState.SOLDOUT.getCode());
            goodsEntity.setUpdateTime(LocalDateTime.now());
            return saveOrUpdate(goodsEntity);
        }

        return Boolean.FALSE;
    }

    @Override
    public Boolean putaway(Long goodsId, String putawayState) {

        QueryWrapper<GoodsEntity> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(GoodsEntity::getCategoryId, goodsId)
                .eq(GoodsEntity::getAudit, GoodsConstant.GoodsAuditState.PASS.getCode())
                .eq(GoodsEntity::getState, Boolean.FALSE);
        GoodsEntity goodsEntity = getOne(qw);
        String typeCode = GoodsConstant.GoodsPutawayState.getTypeCode(putawayState);
        if (typeCode != null) {
            goodsEntity.setPutawayState(typeCode);
            goodsEntity.setPutawayState(GoodsConstant.GoodsAuditState.WAIT.getCode());
            goodsEntity.setUpdateTime(LocalDateTime.now());
            return saveOrUpdate(goodsEntity);
        }

        return Boolean.FALSE;
    }

}
